home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / msdos / raytrace / pov / bin / xtras / render.c < prev   
C/C++ Source or Header  |  1994-09-11  |  17KB  |  621 lines

  1. /****************************************************************************
  2. *
  3. *  ATTENTION!!!
  4. *
  5. *  THIS FILE HAS BEEN MODIFIED!!! IT IS NOT PART OF THE OFFICAL
  6. *  POV-RAY 2.2 DISTRIBUTION!!!
  7. *
  8. *  THIS FILE IS PART OF "FASTER THAN POV-RAY" (VERSION 2.2),
  9. *  A SPED-UP VERSION OF POV-RAY 2.2. USE AT YOUR OWN RISK!!!!!!
  10. *
  11. *  New files: addon0.c, addon1.c, addon2.c, addon3.c, addon.h
  12. *
  13. *  The additional modules were written by Dieter Bayer.
  14. *
  15. *  Send comments, suggestions, bugs, ideas ... to:
  16. *
  17. *  e-mail: dieter@cip.e-technik.uni-erlangen.de
  18. *  CIS: 100255.3074
  19. *
  20. *  All changed/added lines are enclosed in #ifdef DB_CODE ... #endif
  21. *
  22. *  The vista projection was taken from:
  23. *
  24. *    A. Hashimoto, T. Akimoto, K. Mase, and Y. Suenaga, 
  25. *    "Vista Ray-Tracing: High Speed Ray Tracing Using Perspective
  26. *    Projection Image", New Advances in Computer Graphics, Proceedings
  27. *    of CG International '89, R. A. Earnshaw, B. Wyvill (Eds.), 
  28. *    Springer, ..., pp. 549-560
  29. *
  30. *  The idea for the light buffer was taken from:
  31. *
  32. *    E. Haines and D. Greenberg, "The Light Buffer: A Shadow-Testing 
  33. *    Accelerator", IEEE CG&A, Vol. 6, No. 9, Sept. 1986, pp. 6-16
  34. *
  35. *****************************************************************************/
  36.  
  37. /****************************************************************************
  38. *                   render.c
  39. *
  40. *  This module implements the main raytracing loop.
  41. *
  42. * 08/07/92 lsk    Changed the normal antialiasing function to use a loop 
  43. *                 where the number of rays per pixel when antialiasing can 
  44. *                 be sepcified.
  45. *
  46. *  from Persistence of Vision Raytracer
  47. *  Copyright 1993 Persistence of Vision Team
  48. *---------------------------------------------------------------------------
  49. *  NOTICE: This source code file is provided so that users may experiment
  50. *  with enhancements to POV-Ray and to port the software to platforms other
  51. *  than those supported by the POV-Ray Team.  There are strict rules under
  52. *  which you are permitted to use this file.  The rules are in the file
  53. *  named POVLEGAL.DOC which should be distributed with this file. If
  54. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  55. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  56. *  Forum.  The latest version of POV-Ray may be found there as well.
  57. *
  58. * This program is based on the popular DKB raytracer version 2.12.
  59. * DKBTrace was originally written by David K. Buck.
  60. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  61. *
  62. ******************************************************************************/
  63.  
  64. #include "frame.h"
  65. #include "vector.h"
  66. #include "povproto.h"
  67. #ifdef DB_CODE
  68. #include "addon.h"
  69. #endif
  70.  
  71. extern FILE_HANDLE *Output_File_Handle;
  72. extern char Output_File_Name[FILE_NAME_LENGTH];
  73. extern char Input_File_Name[FILE_NAME_LENGTH];
  74. extern char Stat_File_Name[FILE_NAME_LENGTH];
  75. extern char OutputFormat, Color_Bits, PaletteOption;
  76. extern char VerboseFormat;
  77. extern unsigned int Options;
  78. extern int File_Buffer_Size;
  79. extern int Use_Slabs;
  80. volatile int Stop_Flag;
  81. extern int First_Line, Last_Line;
  82. extern int First_Column, Last_Column;
  83. extern long Number_Of_Pixels, Number_Of_Rays, Number_Of_Pixels_Supersampled;
  84. extern short *hashTable;
  85. extern unsigned short crctab[256];
  86. extern OBJECT *Root_Object;
  87. extern long AntialiasDepth;
  88. extern DBL JitterScale;
  89. #ifdef DB_CODE
  90. extern unsigned int Extended_Options;
  91. #endif
  92.  
  93. #define rand3d(a,b) crctab[(int)(hashTable[(int)(hashTable[(int)((a)&0xfff)]^(b))&0xfff])&0xff]
  94.  
  95. FRAME Frame;
  96. RAY *CM_Ray;
  97. int Trace_Level, SuperSampleCount;
  98.  
  99. DBL Max_Trace_Level = 5;
  100. DBL maxclr;
  101.  
  102. static void check_stats PARAMS((int y));
  103. static void do_anti_aliasing PARAMS((int x, int y, COLOUR *Colour));
  104. static void output_line PARAMS((int y));
  105.  
  106. COLOUR *Previous_Line, *Current_Line;
  107.  
  108. char *Previous_Line_Antialiased_Flags, *Current_Line_Antialiased_Flags;
  109. RAY Ray;
  110.  
  111. void Create_Ray (ray, width, height, x, y)
  112. RAY *ray;
  113. int width, height;
  114. DBL x, y;
  115.   {
  116.   register DBL X_Scalar, Y_Scalar;
  117.   VECTOR Temp_Vect_1, Temp_Vect_2;
  118.  
  119.   /* Convert the X Coordinate to be a DBL from 0.0 to 1.0 */
  120.   X_Scalar = (x - (DBL) width / 2.0) / (DBL) width;
  121.  
  122.   /* Convert the Y Coordinate to be a DBL from 0.0 to 1.0 */
  123.   Y_Scalar = (( (DBL)(Frame.Screen_Height - 1) - y) -
  124.     (DBL) height / 2.0) / (DBL) height;
  125.  
  126.   VScale (Temp_Vect_1, Frame.Camera->Up, Y_Scalar);
  127.   VScale (Temp_Vect_2, Frame.Camera->Right, X_Scalar);
  128.   VAdd (ray->Direction, Temp_Vect_1, Temp_Vect_2);
  129.   VAdd (ray->Direction, ray->Direction, Frame.Camera->Direction);
  130.   VNormalize (ray->Direction, ray->Direction);
  131.   Initialize_Ray_Containers (ray);
  132.   ray->Quadric_Constants_Cached = FALSE;
  133.   }
  134.  
  135. void Read_Rendered_Part()
  136.   {
  137.   int rc, x, line_number;
  138.   unsigned char Red, Green, Blue;
  139.   DBL grey;
  140.  
  141.   maxclr = (DBL)(1 << Color_Bits) - 1.0;
  142.   while ((rc = Read_Line(Output_File_Handle, Previous_Line, &line_number)) == 1)
  143.     {
  144.     if (Options & DISPLAY)
  145.       for (x = 0 ; x < Frame.Screen_Width ; x++)
  146.       {
  147.       if (PaletteOption == GREY)
  148.     {
  149.     grey = Previous_Line[x].Red * 0.287 +
  150.     Previous_Line[x].Green * 0.589 +
  151.     Previous_Line[x].Blue * 0.114;
  152.     Red = Green = Blue = (unsigned char)(grey * maxclr);
  153.     }
  154.       else
  155.     {
  156.     Red = (unsigned char) (Previous_Line[x].Red * maxclr);
  157.     Green = (unsigned char) (Previous_Line[x].Green * maxclr);
  158.     Blue = (unsigned char) (Previous_Line[x].Blue * maxclr);
  159.     }
  160.       display_plot (x, line_number, Red, Green, Blue);
  161.       COOPERATE     /* Moved inside loop JLN 12/91 */
  162.     }
  163.       }
  164.  
  165.     First_Line = line_number+1;
  166.  
  167.   if (rc == 0) 
  168.     {
  169.     Close_File(Output_File_Handle);
  170.     if (Open_File (Output_File_Handle, Output_File_Name,
  171.       &Frame.Screen_Width, &Frame.Screen_Height, File_Buffer_Size,
  172.       APPEND_MODE) != 1) 
  173.       {
  174.       fprintf (stderr, "Error opening output file\n");
  175.       fflush(stdout);
  176.       close_all();
  177.       exit(1);
  178.       }
  179.     return;
  180.     }
  181.  
  182.   fprintf (stderr, "Error reading aborted data file\n");
  183.   }
  184.  
  185. void Start_Tracing ()
  186.   {
  187.   COLOUR Colour;
  188.   register int x, y;
  189.   unsigned char Red, Green, Blue;
  190.   DBL grey;
  191.  
  192.   for (y = (Options & ANTIALIAS)?First_Line-1:First_Line; y<Last_Line; y++)
  193.     {
  194.  
  195.     check_stats(y);
  196.  
  197. #ifdef DB_CODE
  198.     /* Necessary for vista buffer. */
  199.     if (Extended_Options & USE_VISTA_BUFFER)
  200.     {
  201.       Prune_Vista_Tree(y);
  202.     }
  203. #endif
  204.  
  205.     for (x = First_Column ; x < Last_Column ; x++)
  206.       {
  207.       Check_User_Abort(1);
  208.  
  209.       Number_Of_Pixels++;
  210.  
  211. #ifdef DB_CODE
  212.       /* Necessary for vista buffer. */
  213.       Create_Ray(CM_Ray, Frame.Screen_Width, Frame.Screen_Height, (DBL) x, (DBL) y);
  214.  
  215.       Trace_Level = 0;
  216.  
  217.       if (Extended_Options & USE_VISTA_BUFFER)
  218.     Trace_Primary_Ray (&Ray, &Colour, x);
  219.       else
  220.     Trace (&Ray, &Colour);
  221. #else
  222.       Create_Ray (CM_Ray, Frame.Screen_Width, Frame.Screen_Height, (DBL) x, (DBL) y);
  223.       Trace_Level = 0;
  224.       Trace (&Ray, &Colour);
  225. #endif
  226.       Clip_Colour (&Colour, &Colour);
  227.  
  228.       Current_Line[x] = Colour;
  229.  
  230.       if (Options & ANTIALIAS)
  231.     do_anti_aliasing(x, y, &Colour);
  232.  
  233.       if (y != First_Line-1)
  234.     {
  235.  
  236.     if (PaletteOption == GREY)
  237.       {
  238.       grey = Colour.Red * 0.287 +
  239.       Colour.Green * 0.589 +
  240.       Colour.Blue * 0.114;
  241.       Red = Green = Blue = (unsigned char)(grey * maxclr);
  242.       }
  243.     else
  244.       {
  245.       Red = (unsigned char) (Colour.Red * maxclr);
  246.       Green = (unsigned char) (Colour.Green * maxclr);
  247.       Blue = (unsigned char) (Colour.Blue * maxclr);
  248.       }
  249.     if (Options & DISPLAY)
  250.       display_plot (x, y, Red, Green, Blue);
  251.     }
  252.       }
  253.     output_line(y);
  254.     }
  255.  
  256.   if (Options & DISKWRITE)
  257.     {
  258.     if (Last_Line != First_Line)
  259.     Write_Line (Output_File_Handle, Previous_Line, Last_Line - 1);
  260.     }
  261.   }
  262.  
  263. static void check_stats(y)
  264. register int y;
  265.   {
  266.   FILE *stat_file;
  267.  
  268.   /* New verbose options CdW */
  269.   if (Options & VERBOSE && VerboseFormat=='0')
  270.     {
  271.     printf ("POV-Ray rendering %s to %s",Input_File_Name,Output_File_Name);
  272.     if((First_Line != 0) || (Last_Line != Frame.Screen_Height))
  273.       printf(" from %4d to %4d:\n",First_Line+1, Last_Line);
  274.     else
  275.       printf (":\n");
  276.     printf ("Res %4d X %4d. Calc line %4d of %4d",Frame.Screen_Width, Frame.Screen_Height, (y-First_Line)+1, Last_Line-First_Line);
  277.     if (!(Options & ANTIALIAS))
  278.       printf(".");
  279.     }
  280.   if (Options & VERBOSE_FILE)
  281.     {
  282.     stat_file = fopen(Stat_File_Name,"w+t");
  283.     fprintf (stat_file,"Line %4d.\n", y);
  284.     fclose(stat_file);
  285.     }
  286.  
  287.   /* Use -vO for Old style verbose */
  288.   if (Options & VERBOSE && (VerboseFormat=='O'))
  289.     {
  290.     printf ("Line %4d", y);
  291.     }
  292.   if (Options & VERBOSE && VerboseFormat=='1')
  293.     {
  294.     fprintf (stderr,"Res %4d X %4d. Calc line %4d of %4d",Frame.Screen_Width, Frame.Screen_Height, (y-First_Line)+1, Last_Line-First_Line);
  295.     if (!(Options & ANTIALIAS))
  296.       fprintf(stderr,".");
  297.     }
  298.  
  299.   if (Options & ANTIALIAS)
  300.     SuperSampleCount = 0;
  301.   }
  302.  
  303. static void do_anti_aliasing(x, y, Colour)
  304. register int x, y;
  305. COLOUR *Colour;
  306.   {
  307.   char Antialias_Center_Flag = 0;
  308.  
  309.   Current_Line_Antialiased_Flags[x] = 0;
  310.  
  311.   if (x != 0)
  312.     {
  313.     if (Colour_Distance (&Current_Line[x-1], &Current_Line[x])
  314.       >= Frame.Antialias_Threshold)
  315.       {
  316.       Antialias_Center_Flag = 1;
  317.       if (!(Current_Line_Antialiased_Flags[x-1]))
  318.     {
  319.     Supersample (&Current_Line[x-1],
  320.       x-1, y, Frame.Screen_Width, Frame.Screen_Height);
  321.     Current_Line_Antialiased_Flags[x-1] = 1;
  322.     SuperSampleCount++;
  323.     }
  324.       }
  325.     }
  326.  
  327.   if (y != First_Line-1)
  328.     {
  329.     if (Colour_Distance (&Previous_Line[x], &Current_Line[x])
  330.       >= Frame.Antialias_Threshold)
  331.       {
  332.       Antialias_Center_Flag = 1;
  333.       if (!(Previous_Line_Antialiased_Flags[x]))
  334.     {
  335.     Supersample (&Previous_Line[x],
  336.       x, y-1, Frame.Screen_Width, Frame.Screen_Height);
  337.     Previous_Line_Antialiased_Flags[x] = 1;
  338.     SuperSampleCount++;
  339.     }
  340.       }
  341.     }
  342.  
  343.   if (Antialias_Center_Flag)
  344.     {
  345.     Supersample (&Current_Line[x],
  346.       x, y, Frame.Screen_Width, Frame.Screen_Height);
  347.     Current_Line_Antialiased_Flags[x] = 1;
  348.     *Colour = Current_Line[x];
  349.     SuperSampleCount++;
  350.     }
  351.  
  352.   return;
  353.   }
  354.  
  355.  
  356. void Initialize_Renderer PARAMS((void))
  357.   {
  358.   register int i;
  359.  
  360.   CM_Ray = &Ray;
  361.  
  362.   maxclr = (DBL)(1 << Color_Bits) - 1.0;
  363.  
  364.   /* These malloc's are never freed! Why ? Need a Deinit_Renderer() ?*/
  365.   Previous_Line = (COLOUR *) malloc (sizeof (COLOUR)*(Frame.Screen_Width + 1));
  366.   Current_Line = (COLOUR *) malloc (sizeof (COLOUR)*(Frame.Screen_Width + 1));
  367.  
  368.   for (i = 0 ; i <= Frame.Screen_Width ; i++)
  369.     {
  370.     Previous_Line[i].Red = 0.0;
  371.     Previous_Line[i].Green = 0.0;
  372.     Previous_Line[i].Blue = 0.0;
  373.     Current_Line[i].Red = 0.0;
  374.     Current_Line[i].Green = 0.0;
  375.     Current_Line[i].Blue = 0.0;
  376.     }
  377.  
  378.   if (Options & ANTIALIAS)
  379.     {
  380.     Previous_Line_Antialiased_Flags =
  381.     (char *) malloc (sizeof (char)*(Frame.Screen_Width + 1));
  382.     Current_Line_Antialiased_Flags =
  383.     (char *)  malloc (sizeof (char)*(Frame.Screen_Width + 1));
  384.  
  385.     for (i = 0 ; i <= Frame.Screen_Width ; i++) 
  386.       {
  387.       (Previous_Line_Antialiased_Flags)[i] = 0;
  388.       (Current_Line_Antialiased_Flags)[i] = 0;
  389.       }
  390.     }
  391.  
  392.   Ray.Initial = Frame.Camera->Location;
  393.   return;
  394.   }
  395.  
  396. static void output_line (y)
  397. register int y;
  398.   {
  399.   COLOUR *Temp_Colour_Ptr;
  400.   char *Temp_Char_Ptr;
  401.  
  402.   if (Options & DISKWRITE)
  403.     if (y > First_Line) 
  404.     {
  405.     Write_Line (Output_File_Handle, Previous_Line, y-1);
  406.     }
  407.  
  408.   if (Options & VERBOSE)
  409.     {
  410.     if (Options & ANTIALIAS && VerboseFormat != '1')
  411.       printf (" supersampled %d times.", SuperSampleCount);
  412.  
  413.     if (Options & ANTIALIAS && VerboseFormat == '1')
  414.       {
  415.       fprintf (stderr," supersampled %d times.", SuperSampleCount);
  416.  
  417.       }
  418.     if (VerboseFormat == '1')
  419.       fprintf (stderr,"\r");
  420.     else
  421.       fprintf (stderr,"\n");
  422.     }
  423.   Temp_Colour_Ptr = Previous_Line;
  424.   Previous_Line = Current_Line;
  425.   Current_Line = Temp_Colour_Ptr;
  426.  
  427.   Temp_Char_Ptr = Previous_Line_Antialiased_Flags;
  428.   Previous_Line_Antialiased_Flags = Current_Line_Antialiased_Flags;
  429.   Current_Line_Antialiased_Flags = Temp_Char_Ptr;
  430.  
  431.   return;
  432.   }
  433.  
  434. void Trace (Ray, Colour)
  435. RAY *Ray;
  436. COLOUR *Colour;
  437.   {
  438.   OBJECT *Object;
  439.   INTERSECTION Best_Intersection, New_Intersection;
  440.   register int Intersection_Found;
  441.  
  442.   COOPERATE
  443.   Number_Of_Rays++;
  444.   Make_Colour (Colour, 0.0, 0.0, 0.0);
  445.  
  446.   if (Trace_Level > (int) Max_Trace_Level)
  447.     return;
  448.  
  449.   Intersection_Found = FALSE;
  450.   Best_Intersection.Depth = BOUND_HUGE;
  451.  
  452.     /* What objects does this ray intersect? */
  453.   if (!Use_Slabs)
  454.     for (Object = Frame.Objects ;
  455.      Object != NULL ;
  456.      Object = Object -> Sibling)
  457.     {
  458.     if (Intersection (&New_Intersection, Object, Ray))
  459.       if (New_Intersection.Depth < Best_Intersection.Depth)
  460.     {
  461.     Best_Intersection = New_Intersection;
  462.     Intersection_Found = TRUE;
  463.     }
  464.     }
  465.   else
  466.     Intersection_Found = Bounds_Intersect(Root_Object, Ray,
  467.       &Best_Intersection,&Object);
  468.  
  469.   if (Intersection_Found)
  470.     Determine_Apparent_Colour (&Best_Intersection, Colour, Ray);
  471.   else
  472.     if (Frame.Fog_Distance > 0.0)
  473.       *Colour = Frame.Fog_Colour;
  474.     else
  475.       *Colour = Frame.Background_Colour;
  476.   }
  477.  
  478. /* exit with error if image not completed/user abort*/
  479. void Check_User_Abort (Do_Stats)
  480. int Do_Stats;
  481.   {
  482.   TEST_ABORT
  483.   if (Stop_Flag)
  484.     {
  485.     close_all();
  486.     if (Do_Stats)
  487.       {
  488.       PRINT_STATS
  489.       }
  490.     exit(2);
  491.     }
  492.   }
  493.  
  494. /*---------------  Standard sampling in loop  -----------------------*/
  495.  
  496. unsigned short JRanges[] = {1,1,1,1,3,2,5,3,7,4}; /* LSK */
  497.  
  498. void Supersample (result, x, y, Width, Height)
  499. COLOUR *result;
  500. int x, y, Width, Height;
  501.   {
  502.   COLOUR colour;
  503.   register DBL dx, dy, Jitter_X, Jitter_Y;
  504.   register int Jitt_Offset;
  505.   unsigned char Red, Green, Blue;
  506.   int JRange;                               /* LSK */
  507.   int JSteps;                               /* LSK */
  508.   DBL JScale;                               /* LSK */
  509.   DBL JSize,JOffset;                        /* LSK */
  510.   int i,j;                                  /* LSK */
  511.  
  512.   dx = (DBL) x;                             /* LSK */
  513.   dy = (DBL) y;                             /* LSK */
  514.   Jitt_Offset = 10;
  515.  
  516.   Number_Of_Pixels_Supersampled++;
  517.  
  518.   Make_Colour (result, 0.0, 0.0, 0.0);
  519.  
  520.   if (AntialiasDepth>1)                                           /* LSK */
  521.     {                                                             /* LSK */
  522.     /* JSize is the size of the jitter scattering area */
  523.     JSize = 1.0/AntialiasDepth;                                   /* LSK */
  524.  
  525.     /* JOffset is the 'radius' of the jitter scatter area */
  526.     JOffset = JSize/2.0;                                        /* LSK */
  527.  
  528.     /* JSteps is either 1 or 2 depending on whether the number of samples
  529.     is odd or even. This is because the loop need to either run through
  530.     or over 0
  531.      */
  532.     JSteps = 2-(AntialiasDepth % 2);                              /* LSK */
  533.  
  534.     /* JRange is the range that the loop will run through. I couldn't
  535.     come up with a function describing the values, so I used an array
  536.     for 2x2 up to 9x9.
  537.      */
  538.     JRange = JRanges[AntialiasDepth];                             /* LSK */
  539.  
  540.     /* JScale is the scaling value for the color resulting from the
  541.     ray before adding to the resultant color
  542.      */
  543.     JScale = 1.0/(DBL)(AntialiasDepth*AntialiasDepth);              /* LSK */
  544.  
  545.     for (i= -JRange;i<=JRange;i+=JSteps)
  546.       for (j= -JRange;j<=JRange;j+=JSteps)
  547.       {
  548.       if (Options & JITTER)
  549.     {
  550.     Jitter_X = (rand3d(x+Jitt_Offset, y) & 0x7FFF) / 32768.0 * JSize - JOffset;
  551.     Jitt_Offset++;
  552.     Jitter_Y = (rand3d(x+Jitt_Offset, y) & 0x7FFF) / 32768.0 * JSize - JOffset;
  553.     Jitt_Offset++;
  554.     }
  555.       else
  556.     {
  557.     Jitter_X=Jitter_Y=0.0;
  558.     }
  559.       Jitter_X*=JitterScale;
  560.       Jitter_Y*=JitterScale;
  561.  
  562. #ifdef DB_CODE
  563.       /* Necessary for vista buffer. */
  564.       Create_Ray (CM_Ray, Frame.Screen_Width, Frame.Screen_Height,
  565.         dx + Jitter_X + i * JSize/JSteps,
  566.         dy + Jitter_Y + j * JSize/JSteps);
  567.  
  568.       Trace_Level = 0;
  569.  
  570.       if (Extended_Options & USE_VISTA_BUFFER)
  571.     Trace_Primary_Ray (CM_Ray, &colour, x);
  572.       else
  573.     Trace (CM_Ray, &colour);
  574. #else
  575.       Create_Ray (CM_Ray, Frame.Screen_Width, Frame.Screen_Height,
  576.     dx + Jitter_X + i * JSize/JSteps,
  577.     dy + Jitter_Y + j * JSize/JSteps );
  578.  
  579.       Trace_Level = 0;
  580.       Trace (CM_Ray, &colour);
  581. #endif
  582.       Clip_Colour (&colour, &colour);
  583.       Scale_Colour (&colour, &colour, JScale );
  584.       Add_Colour (result, result, &colour);
  585.  
  586.       }
  587.     }                                       /* LSK */
  588.   else   /* 1x1 specified! */
  589.     {
  590. #ifdef DB_CODE
  591.     /* Necessary for vista buffer. */
  592.     Create_Ray (CM_Ray, Frame.Screen_Width, Frame.Screen_Height,dx,dy);
  593.  
  594.     Trace_Level = 0;
  595.  
  596.     if (Extended_Options & USE_VISTA_BUFFER)
  597.       Trace_Primary_Ray (CM_Ray, &colour, x);
  598.     else
  599.       Trace (CM_Ray, &colour);
  600. #else
  601.     Create_Ray (CM_Ray, Frame.Screen_Width, Frame.Screen_Height,dx,dy );
  602.  
  603.     Trace_Level = 0;
  604.     Trace (CM_Ray, &colour);
  605. #endif
  606.     Clip_Colour (&colour, &colour);
  607.     Add_Colour (result, result, &colour);
  608.     Jitt_Offset += 10;
  609.     }
  610.  
  611.   if ((y != First_Line - 1) && (Options & DISPLAY))
  612.     {
  613.     Red = (unsigned char)(result->Red * maxclr);
  614.     Green = (unsigned char)(result->Green * maxclr);
  615.     Blue = (unsigned char)(result->Blue * maxclr);
  616.     display_plot (x, y, Red, Green, Blue);
  617.     }
  618.  
  619.   }
  620.  
  621.